package com.biboheart.adapter.express.support;

import com.biboheart.adapter.express.operation.Calculate;

import java.util.HashMap;
import java.util.Map;

public class GenericOperationService implements ConfigurableOperationService{
    private final Operations operations = new Operations();

    @Override
    public <T, S, U extends Number> void addOperator(String character, Calculate<T, S, U> calculate) {
        operations.add(character, calculate);
    }

    @Override
    public void removeOperator(String character) {
        operations.remove(character);
    }

    @Override
    public <T, S, U extends Number> T execute(String character, S num) {
        Calculate<T, S, U> calculate = operations.getCalculate(character);
        if (null == calculate) {
            return null;
        }
        return calculate.calc(num);
    }

    @Override
    public <T, S, U extends Number> T execute(String character, S left, U right) {
        Calculate<T, S, U> calculate = operations.getCalculate(character);
        if (null == calculate) {
            return null;
        }
        return calculate.calc(left, right);
    }

    private static class Operations {
        private final Map<String, Calculate<?, ?, ?>> calculateHash = new HashMap<>();

        public void add(String name, Calculate<?, ?, ?> calculate) {
            calculateHash.put(name, calculate);
        }

        public void remove(String name) {
            calculateHash.remove(name);
        }

        @SuppressWarnings("unchecked")
        public <T, S, U extends Number> Calculate<T, S, U> getCalculate(String name) {
            if ("".equals(name) || null == name) {
                return null;
            }
            return (Calculate<T, S, U>) calculateHash.get(name);
        }
    }
}
